package com.foreveross.mofang.datapersistence.application.impl;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import javax.inject.Inject;

import org.dayatang.querychannel.Page;
import org.dayatang.querychannel.QueryChannelService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;

import com.foreveross.mofang.datapersistence.application.RDBMSBase;
import com.foreveross.mofang.datapersistence.application.vo.RDBMSDataVo;
import com.foreveross.mofang.datapersistence.core.RDBMSBaseEntity;

/**
 * 关系性数据库基本操作接口实现
 * 
 * @author fb
 */
@Transactional
public abstract class RDBMSBaseImpl<T extends RDBMSBaseEntity> implements RDBMSBase {
	
	protected final Logger logger = LoggerFactory.getLogger(this.getClass());

	@Inject
	protected  QueryChannelService queryChannel;
	
	private Class<T> clazz;
	
	/**
	 *  根据实例类自动获取实体类类型
	 */
	@SuppressWarnings({"unchecked" })
	public RDBMSBaseImpl() {
        Type t = getClass().getGenericSuperclass();
        if (t instanceof ParameterizedType) {
            Type[] p = ((ParameterizedType) t).getActualTypeArguments();
            this.clazz = (Class<T>) p[0];
        }
    }

	@SuppressWarnings("unchecked")
	protected Page<RDBMSDataVo> pageQuery(int currentPage, int pageSize, String hql) {
		Page<RDBMSBaseEntity> page = queryChannel
				.createJpqlQuery(hql)
				.setPage(currentPage, pageSize)
				.pagedList();
		
		List<RDBMSDataVo> result = new ArrayList<RDBMSDataVo>();
		
		for (RDBMSBaseEntity rdbms : page.getData()) {
			result.add(domainToVo(rdbms));
		}
	
		return new Page<RDBMSDataVo>(currentPage, page.getPageCount(), pageSize, result);
	}

	public RDBMSDataVo get(Long id) {
		return domainToVo(RDBMSBaseEntity.get(clazz, id));
	}

	public void deletes(Long... ids) {
		for (Long id : ids) {
			RDBMSBaseEntity.get(clazz, id).remove();
		}
	}

	public void update(Long id, RDBMSDataVo rdbms) {
		RDBMSBaseEntity rbe = RDBMSBaseEntity.get(clazz, id);
		rbe.setContent(rdbms.getContent() == null ? rbe.getContent() : rdbms.getContent());
		rbe.setRowKey(rdbms.getRowKey() == null ? rbe.getRowKey() : rdbms.getRowKey());
		rbe.setCreateDate(rdbms.getCreateDate() == null ?  rbe.getCreateDate() : rdbms.getCreateDate());
		rbe.save();
	}
	
	protected RDBMSDataVo domainToVo(RDBMSBaseEntity rdbms) {
		if (rdbms == null) {
			return null;
		}
		
		return new RDBMSDataVo(rdbms.getRowKey(), rdbms.getContent(), rdbms.getId());
	}

}
